package com.alibaba.citrus.cr.platform.enhance.functions.customer;

import com.alibaba.citrus.cr.common.exception.FunctionException;
import com.alibaba.citrus.cr.common.util.SpringContextUtil;
import com.alibaba.citrus.cr.platform.enhance.repository.CustomerAddressRelationRepository;
import com.alibaba.cz.base.tool.Nullable;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.bcorder.contants.BcOrderConstants;
import com.epoch.app.bcorder.model.dto.BaselineGetEmployeeByIdsAllRequest;
import com.epoch.app.bcorder.model.dto.BaselineGetEmployeesEs2Request;
import com.epoch.app.bcorder.model.dto.EmployeeSDO;
import com.epoch.app.bcorder.model.dto.RoleSDO;
import com.epoch.app.bcorder.service.BaseDataService;
import com.epoch.app.crplatformenhance.contants.CrPlatformEnhanceConstants;
import com.epoch.app.crplatformenhance.model.dto.CustomerAddressRelationLoadListRequest;
import com.epoch.app.crplatformenhance.model.dto.CustomerAddressRelationSDO;
import com.epoch.app.crplatformenhance.model.dto.GetEmployeeRolesRequest;
import com.epoch.app.crplatformenhance.model.enums.CustomerRelationBizTypeEnum;
import com.epoch.app.crplatformenhance.sdo.CustomerAddressSDO;
import com.epoch.app.crplatformenhance.sdo.CustomerSaleScopeSDO;
import com.epoch.app.crplatformenhance.service.CrPlatformEnhanceService;
import com.google.common.collect.Lists;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author zhoubc
 * @description: TODO
 * @date 2022/8/5 22:23
 */
public class CustomerAddressRelationEntity {

    @Getter
    @Setter
    private CustomerAddressSDO sdo;

    @Getter
    @Setter
    private CustomerSaleScopeSDO customerSaleScopeSDO;

    private static CustomerAddressRelationRepository customerAddressRelationRepository;

    private static BaseDataService baseDataService;

    private static CrPlatformEnhanceService crPlatformEnhanceService;

    static {
        customerAddressRelationRepository = SpringContextUtil.getBean(CustomerAddressRelationRepository.class);
        baseDataService = SpringContextUtil.getBean(BaseDataService.class);
        crPlatformEnhanceService = SpringContextUtil.getBean(CrPlatformEnhanceService.class);
    }

    public static CustomerAddressRelationEntity of(CustomerAddressSDO sdo) {
        CustomerAddressRelationEntity entity = new CustomerAddressRelationEntity();
        entity.setSdo(sdo);
        return entity;
    }

    public static CustomerAddressRelationEntity of(CustomerSaleScopeSDO sdo) {
        CustomerAddressRelationEntity entity = new CustomerAddressRelationEntity();
        entity.setCustomerSaleScopeSDO(sdo);
        return entity;
    }

    public Boolean saveCustomerAddressPrincipal() {
        CustomerAddressRelationLoadListRequest request = new CustomerAddressRelationLoadListRequest();
        request.setAddressId(sdo.getId());
        request.setAddressCode(sdo.getAddressCode());
        request.setBizType(CustomerRelationBizTypeEnum.ADDRESS_CUSTOMER_PRINCIPAL_RELATION.getValue());
        List<CustomerAddressRelationSDO> list = customerAddressRelationRepository.queryRelationList(request);
        Map<String,CustomerAddressRelationSDO> relationMap = Nullable.stream(list).collect(Collectors.toMap(CustomerAddressRelationSDO::getRelationId, Function.identity(),(v1,v2)->v1));
        Nullable.stream(sdo.getCustomerPrincipalList()).forEach(x -> {
            if(relationMap.get(x) == null){
                BaselineGetEmployeeByIdsAllRequest GetEmployeeRequest = new BaselineGetEmployeeByIdsAllRequest();
                GetEmployeeRequest.setIds(Lists.newArrayList(x));
                Result<List<EmployeeSDO>> employeeResult = baseDataService.baselineGetEmployeeByIdsAll(GetEmployeeRequest);
                if(CollectionUtils.isNotEmpty(employeeResult.getResult())){
                    CustomerAddressRelationSDO relationSDO = new CustomerAddressRelationSDO();
                    relationSDO.setAddressId(sdo.getId());
                    relationSDO.setAddressCode(sdo.getAddressCode());
                    relationSDO.setRelationId(x);
                    relationSDO.setRelationName(employeeResult.getResult().get(0).getName());
                    Map map = new HashMap<String,String>();
                    map.put("nick",employeeResult.getResult().get(0).getNick());
                    relationSDO.setFeatures(JSONObject.toJSONString(map));
                    Boolean b = customerAddressRelationRepository.createAddressRelation(relationSDO);
                }
            }else{
                relationMap.remove(x);
            }
        });
        if(MapUtils.isNotEmpty(relationMap)){
            CustomerAddressRelationSDO sdo = new CustomerAddressRelationSDO();
            sdo.setIds(relationMap.values().stream().map(x->x.getId()).collect(Collectors.toList()));
            Integer count = customerAddressRelationRepository.deleteAddressRelation(sdo);
        }
       return true;
    }

    public Boolean saveCustomerSaleScopePrincipal() {
        CustomerAddressRelationLoadListRequest request = new CustomerAddressRelationLoadListRequest();
        request.setAddressId(customerSaleScopeSDO.getId());
        request.setAddressCode(customerSaleScopeSDO.getCustomerCode());
        request.setBizType(CustomerRelationBizTypeEnum.SALESCOPE_CUSTOMER_PRINCIPAL_RELATION.getValue());
        List<CustomerAddressRelationSDO> list = customerAddressRelationRepository.queryRelationList(request);
        Map<String,CustomerAddressRelationSDO> relationMap = Nullable.stream(list).collect(Collectors.toMap(CustomerAddressRelationSDO::getRelationId, Function.identity(),(v1,v2)->v1));
        Nullable.stream(customerSaleScopeSDO.getCustomerPrincipalList()).forEach(x -> {
            if(relationMap.get(x) == null){
                BaselineGetEmployeeByIdsAllRequest GetEmployeeRequest = new BaselineGetEmployeeByIdsAllRequest();
                GetEmployeeRequest.setIds(Lists.newArrayList(x));
                Result<List<EmployeeSDO>> employeeResult = baseDataService.baselineGetEmployeeByIdsAll(GetEmployeeRequest);
                if(CollectionUtils.isNotEmpty(employeeResult.getResult())){
                    CustomerAddressRelationSDO relationSDO = new CustomerAddressRelationSDO();
                    relationSDO.setAddressId(customerSaleScopeSDO.getId());
                    relationSDO.setAddressCode(customerSaleScopeSDO.getCustomerCode());
                    relationSDO.setRelationId(x);
                    relationSDO.setRelationName(employeeResult.getResult().get(0).getName());
                    Map map = new HashMap<String,String>();
                    map.put("nick",employeeResult.getResult().get(0).getNick());
                    relationSDO.setFeatures(JSONObject.toJSONString(map));
                    Boolean b = customerAddressRelationRepository.createSaleScopeRelation(relationSDO);
                }
            }else{
                relationMap.remove(x);
            }
        });
        if(MapUtils.isNotEmpty(relationMap)){
            CustomerAddressRelationSDO sdo = new CustomerAddressRelationSDO();
            sdo.setIds(relationMap.values().stream().map(x->x.getId()).collect(Collectors.toList()));
            Integer count = customerAddressRelationRepository.deleteAddressRelation(sdo);
        }
        return true;
    }

    public Map<String,List<String>> queryEmployeeIdsByNicks(List<String> nicks){
        Map<String,List<String>> resultMap = new HashMap();
        List<EmployeeSDO> empoloyeeSDOS = new ArrayList<>();
        List<String> errorEmployees = new ArrayList<>();

        for (String nick:nicks) {
            BaselineGetEmployeesEs2Request getEmployeesEs2Request = new BaselineGetEmployeesEs2Request();
            getEmployeesEs2Request.setNick(nick);
            getEmployeesEs2Request.setType(1);
            Result<List<EmployeeSDO>> result = baseDataService.baselineGetEmployeesEs2(getEmployeesEs2Request);
            if(result!=null && CollectionUtils.isNotEmpty(result.getResult())){
                empoloyeeSDOS.add(result.getResult().get(0));
            }else{
                errorEmployees.add(nick);
            }
        }

        if(empoloyeeSDOS.size() != nicks.size()){
            resultMap.put("errorEmployees",errorEmployees);
            return resultMap;
        }

        List<String> errorEmployeeRoles = new ArrayList<>();
        for (EmployeeSDO empoloyee:empoloyeeSDOS) {
            GetEmployeeRolesRequest getEmployeeRolesRequest = new GetEmployeeRolesRequest();
            getEmployeeRolesRequest.setId(empoloyee.getId());
            Result<List<RoleSDO>> result2 = crPlatformEnhanceService.getEmployeeRoles(getEmployeeRolesRequest);
            if(result2!=null && CollectionUtils.isNotEmpty(result2.getResult())){
                List<RoleSDO> filter = result2.getResult().stream().filter(x->isCustomerEmployee(x.getCode())).collect(Collectors.toList());
                if(CollectionUtils.isEmpty(filter)){
                    errorEmployeeRoles.add(empoloyee.getNick());
                }
            }else{
                errorEmployeeRoles.add(empoloyee.getNick());
            }
        }

        if(CollectionUtils.isNotEmpty(errorEmployeeRoles)){
            resultMap.put("errorEmployeeRoles",errorEmployeeRoles);
            return resultMap;
        }

        List<String> ids = empoloyeeSDOS.stream().map(x->x.getId()).collect(Collectors.toList());
        resultMap.put("ids",ids);
        return resultMap;
    }

    public Map<String,List<String>> queryEmployeeIdsByNames(List<String> names){
        Map<String,List<String>> resultMap = new HashMap();
        List<EmployeeSDO> empoloyeeSDOS = new ArrayList<>();
        List<String> errorEmployees = new ArrayList<>();

        for (String name:names) {
            BaselineGetEmployeesEs2Request getEmployeesEs2Request = new BaselineGetEmployeesEs2Request();
            getEmployeesEs2Request.setName(name);
            getEmployeesEs2Request.setType(1);
            Result<List<EmployeeSDO>> result = baseDataService.baselineGetEmployeesEs2(getEmployeesEs2Request);
            if(result!=null && CollectionUtils.isNotEmpty(result.getResult())){
                empoloyeeSDOS.add(result.getResult().get(0));
            }else{
                errorEmployees.add(name);
            }
        }

        if(empoloyeeSDOS.size() != names.size()){
            resultMap.put("errorEmployees",errorEmployees);
            return resultMap;
        }

        List<String> errorEmployeeRoles = new ArrayList<>();
        for (EmployeeSDO empoloyee:empoloyeeSDOS) {
            GetEmployeeRolesRequest getEmployeeRolesRequest = new GetEmployeeRolesRequest();
            getEmployeeRolesRequest.setId(empoloyee.getId());
            Result<List<RoleSDO>> result2 = crPlatformEnhanceService.getEmployeeRoles(getEmployeeRolesRequest);
            if(result2!=null && CollectionUtils.isNotEmpty(result2.getResult())){
                List<RoleSDO> filter = result2.getResult().stream().filter(x->isCustomerEmployee(x.getCode())).collect(Collectors.toList());
                if(CollectionUtils.isEmpty(filter)){
                    errorEmployeeRoles.add(empoloyee.getName());
                }
            }else{
                errorEmployeeRoles.add(empoloyee.getName());
            }
        }

        if(CollectionUtils.isNotEmpty(errorEmployeeRoles)){
            resultMap.put("errorEmployeeRoles",errorEmployeeRoles);
            return resultMap;
        }

        List<String> ids = empoloyeeSDOS.stream().map(x->x.getId()).collect(Collectors.toList());
        resultMap.put("ids",ids);
        return resultMap;
    }

    public Boolean checkEmployeeCustomerRole(List<String> ids){
        if(CollectionUtils.isEmpty(ids)){
            return true;
        }

        Result<List<EmployeeSDO>> result = baseDataService.baselineGetEmployeeByIdsAll(BaselineGetEmployeeByIdsAllRequest.builder().ids(ids).build());
        if (result==null || CollectionUtils.isEmpty(result.getResult())){
            throw new FunctionException("OTS-01-004-02-16-031");
        }
        if (result.getResult().size() != ids.size()){
            throw new FunctionException("OTS-01-004-02-16-031");
        }

        for (String id:ids) {
            GetEmployeeRolesRequest getEmployeeRolesRequest = new GetEmployeeRolesRequest();
            getEmployeeRolesRequest.setId(id);
            Result<List<RoleSDO>> result2 = crPlatformEnhanceService.getEmployeeRoles(getEmployeeRolesRequest);
            if(result2!=null && CollectionUtils.isNotEmpty(result2.getResult())){
                List<RoleSDO> filter = result2.getResult().stream().filter(x->isCustomerEmployee(x.getCode())).collect(Collectors.toList());
                if(CollectionUtils.isEmpty(filter)){
                    throw new FunctionException("OTS-01-004-02-16-032");
                }
            }else{
                throw new FunctionException("OTS-01-004-02-16-032");
            }
        }
        return true;
    }


    private Boolean isCustomerEmployee(String roleCode){
        String configOutCustomerRoleCodes = BcOrderConstants.OUT_CUSOMER_ROLE_CODES_FOR_CUSTOMER();
        if (StringUtils.isBlank(configOutCustomerRoleCodes)) {
            return false;
        }
        List customerRoleCodeList = Arrays.asList(configOutCustomerRoleCodes.split(",|，"));
        return customerRoleCodeList.contains(roleCode);
    }


}
